package com.clw.classpath;

import com.clw.utils.FileUtil;
import com.clw.utils.PathUtil;
import java.io.File;
import java.io.IOException;

/**
 * Created by chengliwei on 2018/12/14.
 */
public class ClassPath {

    private String className;
    private Entry bootClassPath;
    private Entry extClassPath;
    private Entry userClassPath;

    private ClassPath() {
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public Entry getBootClassPath() {
        return bootClassPath;
    }

    public void setBootClassPath(Entry bootClassPath) {
        this.bootClassPath = bootClassPath;
    }

    public Entry getExtClassPath() {
        return extClassPath;
    }

    public void setExtClassPath(Entry extClassPath) {
        this.extClassPath = extClassPath;
    }

    public Entry getUserClassPath() {
        return userClassPath;
    }

    public void setUserClassPath(Entry userClassPath) {
        this.userClassPath = userClassPath;
    }

    public static ClassPath parse(String jreOption) {
        ClassPath classPath = new ClassPath();
        parseBootAndExtClassPath(classPath, jreOption);
        parseUserClassPath(classPath, jreOption);
        return classPath;
    }

    public byte[] readClass(String className) {
        try {
            byte[] bootFind = bootClassPath.readClass(className);
            if (bootFind == null) {
                bootFind = extClassPath.readClass(className);
                if (bootFind == null) {
                    bootFind = userClassPath.readClass(className);
                }
            }
            return bootFind;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static void parseUserClassPath(ClassPath classPath, String jreOption) {
        if (jreOption == null || jreOption == "") {
            jreOption = ".";
        }
        classPath.setUserClassPath(new DirEntry(jreOption));
    }

    private static void parseBootAndExtClassPath(ClassPath classPath, String jreOption) {
        String jreDir = getJreDir(jreOption);
        if(jreDir == null){
            System.out.println("jre dir can not be null");
        }
        // jre/lib/*
        String jreLibPath = PathUtil.join(jreDir, "jre", "lib", "*");
        classPath.setBootClassPath(new WildcardEntry(jreLibPath));
        // jre/lib/ext/*
        String jreExtPath = PathUtil.join(jreDir, "jre", "lib", "ext", "*");
        classPath.setExtClassPath(new WildcardEntry(jreExtPath));
    }

    private static String getJreDir(String jreOption) {
        if (jreOption != null && FileUtil.exists(jreOption)) {
            return jreOption;
        }
        if (FileUtil.exists("./jre")) {
            return "./jre";
        }
        String javaHome = System.getenv("JAVA_HOME");
        return javaHome != "" ? javaHome : null;
    }

    @Override
    public String toString() {
        return "ClassPath{" +
                "className='" + className + '\'' +
                ", bootClassPath=" + bootClassPath +
                ", extClassPath=" + extClassPath +
                ", userClassPath=" + userClassPath +
                '}';
    }
}
